/*===========================================================================*\
*                                                                           *
*                               OpenMesh                                    *
*      Copyright (C) 2001-2005 by Computer Graphics Group, RWTH Aachen      *
*                           www.openmesh.org                                *
*                                                                           *
*---------------------------------------------------------------------------* 
*                                                                           *
*                                License                                    *
*                                                                           *
*  This library is free software; you can redistribute it and/or modify it  *
*  under the terms of the GNU Library General Public License as published   *
*  by the Free Software Foundation, version 2.                              *
*                                                                           *
*  This library is distributed in the hope that it will be useful, but      *
*  WITHOUT ANY WARRANTY; without even the implied warranty of               *
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU        *
*  Library General Public License for more details.                         *
*                                                                           *
*  You should have received a copy of the GNU Library General Public        *
*  License along with this library; if not, write to the Free Software      *
*  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                *
*                                                                           *
\*===========================================================================*/

// ----------------------------------------------------------------------------

#ifndef OPENMESH_KERNEL_OSG_VECTORADAPTER_HH
#define OPENMESH_KERNEL_OSG_VECTORADAPTER_HH


//== INCLUDES =================================================================

#include <OpenSG/OSGGeometry.h>
#include <Core/Utils/vector_cast.hh>

//== NAMESPACES ===============================================================

namespace OpenMesh {

	//== CLASS DEFINITION =========================================================

	// ----------------------------------------------------------------- class ----

#define OSG_VECTOR_TRAITS( VecType ) \
	template <> struct vector_traits< VecType > { \
	typedef VecType                vector_type; \
	typedef vector_type::ValueType value_type;  \
	typedef GenProg::Int2Type< vector_type::_iSize > typed_size; \
	\
	static const size_t size_ = vector_type::_iSize; \
	static size_t size() { return size_; } \
}

	/// Vector traits for OpenSG vector type
	OSG_VECTOR_TRAITS( osg::Pnt4f );
	/// Vector traits for OpenSG vector type
	OSG_VECTOR_TRAITS( osg::Pnt3f );
	/// Vector traits for OpenSG vector type
	OSG_VECTOR_TRAITS( osg::Pnt2f );

	/// Vector traits for OpenSG vector type
	OSG_VECTOR_TRAITS( osg::Vec4f );
	/// Vector traits for OpenSG vector type
	OSG_VECTOR_TRAITS( osg::Vec3f );
	/// Vector traits for OpenSG vector type
	OSG_VECTOR_TRAITS( osg::Vec2f );

	/// Vector traits for OpenSG vector type
	OSG_VECTOR_TRAITS( osg::Pnt4d );
	/// Vector traits for OpenSG vector type
	OSG_VECTOR_TRAITS( osg::Pnt3d );
	/// Vector traits for OpenSG vector type
	OSG_VECTOR_TRAITS( osg::Pnt2d );

	/// Vector traits for OpenSG vector type
	OSG_VECTOR_TRAITS( osg::Vec4d );
	/// Vector traits for OpenSG vector type
	OSG_VECTOR_TRAITS( osg::Vec3d );

	/// Vector traits for OpenSG vector type
	OSG_VECTOR_TRAITS( osg::Vec4ub );


	// ----------------------------------------------------------------------------


#define OSG_COLOR_TRAITS( VecType, N ) \
	template <> struct vector_traits< VecType > { \
	typedef VecType                vector_type; \
	typedef vector_type::ValueType value_type;  \
	typedef GenProg::Int2Type< N > typed_size; \
	\
	static const size_t size_ = N; \
	static size_t size() { return size_; } \
	}


	/// Vector traits for OpenSG color type
	OSG_COLOR_TRAITS( osg::Color3ub, 3 );
	/// Vector traits for OpenSG color type
	OSG_COLOR_TRAITS( osg::Color4ub, 4 );
	/// Vector traits for OpenSG color type
	OSG_COLOR_TRAITS( osg::Color3f,  3 );
	/// Vector traits for OpenSG color type
	OSG_COLOR_TRAITS( osg::Color4f,  4 );

#undef OSG_VECTOR_TRAITS


	// ----------------------------------------
#if 1
#define PNT2VEC_CASTER( DST, SRC ) \
	template <> struct vector_caster< DST, SRC > { \
	typedef DST   dst_t; \
	typedef SRC   src_t; \
	typedef const dst_t& return_type; \
	inline static return_type cast( const src_t& _src ) {\
	return _src.subZero(); \
	} \
	}

	/// convert Pnt3f to Vec3f
	PNT2VEC_CASTER( osg::Vec3f, osg::Pnt3f );

	/// convert Pnt4f to Vec4f
	PNT2VEC_CASTER( osg::Vec4f, osg::Pnt4f );

	/// convert Pnt3d to Vec3d
	PNT2VEC_CASTER( osg::Vec3d, osg::Pnt3d );

	/// convert Pnt4d to Vec4d
	PNT2VEC_CASTER( osg::Vec4d, osg::Pnt4d );

#undef PNT2VEC
#else

	template <> 
	struct vector_caster< osg::Vec3f, osg::Pnt3f > 
	{
		typedef osg::Vec3f   dst_t;
		typedef osg::Pnt3f   src_t;

		typedef const dst_t& return_type;
		inline static return_type cast( const src_t& _src ) 
		{
			std::cout << "casting Pnt3f to Vec3f\n";
			return _src.subZero();
		}
	};

#endif
	// ----------------------------------------

	//@{
	/// Adapter for osg vector member computing a scalar product
	inline
		osg::Vec3f::ValueType dot( const osg::Vec3f &_v1, const osg::Vec3f &_v2 )
	{ return _v1.dot(_v2); }


	inline
		osg::Vec3f::ValueType dot( const osg::Vec3f &_v1, const osg::Pnt3f &_v2 )
	{ return _v1.dot(_v2); }


	inline
		osg::Vec2f::ValueType dot( const osg::Vec2f &_v1, const osg::Vec2f &_v2 )
	{ return _v1.dot(_v2); }


	inline
		osg::Vec3f cross( const osg::Vec3f &_v1, const osg::Vec3f &_v2 )
	{ return _v1.cross(_v2); }
	//@}

	//=============================================================================
} // namespace OpenMesh
//=============================================================================
#endif // OPENMESH_VECTORADAPTER_HH defined
//=============================================================================

